package controllers;

import models.EEntity;
import java.util.ArrayList;
import java.util.Date;

import java.util.List;

import javax.mail.Session;

import controllers.Browse;
import controllers.Users;

import models.ActionLog;
import models.Organization;
import models.Role;
import models.RoleInOrganization;
import models.User;
import play.data.validation.Email;
import play.data.validation.Required;
import play.mvc.Controller;

public class Organizations extends Controller {

	/**
	 * @author Zeyad Gasser
	 * @userStory 11
	 * @component C1 Creates a new organization, checking the name of the
	 *            organization is not already in use and the user has to be
	 *            logged in
	 * 
	 * @param orgName
	 *            , the name of the organization
	 * @param orgDescription
	 *            , the description of the organization
	 * @param orgPrivacy
	 *            , the privacy of the organization. 0 indicates PUBLIC, 1
	 *            indicates PRIVATE, 2 indicates SECRET
	 * @param leadEmail
	 *            , the email of the user who will become the lead of this
	 *            organization
	 */
	public static void createOrganization(String orgName,
			String orgDescription, int orgPrivacy) {
		validation.required(orgName).message(
				"Please enter the Organization name");
		validation.required(orgDescription).message(
				"Please enter the description of the Organization");
		validation.required(orgPrivacy).message(
				"Please choose the privacy of the Organization");
		if (validation.hasErrors()) {
			params.flash();
			validation.keep();
			createOrg();
		}
		Organization organizationByName = Organization
				.getOrganizationByName(orgName);
		if (organizationByName != null) {
			render("Organizations/createOrgFail.html");
		}
		String userName = session.get("username");
		if (userName == null) {
			render("Application/notLoggedIn.html");
		} else {
			Organization org = new Organization(orgName, orgDescription,
					orgPrivacy).save();
			Role role = Role.findOrCreate("OrganizationLead").save();
			User user = User.getUserInfo(userName);
			new RoleInOrganization(org, user, role).save();
			user.followedOrgs.add(org);
			org.followingUsers.add(user);
			user.save();
			org.save();
			String blockedUserIdMsg = "User name " + user.name
					+ " created a new Organization called " + org.name;
			new ActionLog(blockedUserIdMsg, user, null).save();
			editOrg(org.id);
		}
	}

	/**
	 * Method to edit an organization's name, description
	 * and privacy status
	 * 
	 * @param orgId
	 *            , id of the org
	 * @param orgName
	 *            , name of the org
	 * @param orgDescription
	 *            , description of the org
	 * @param privacy
	 *            , privacy status of the org
	 * @author Omar Fouda
	 */
	public static void editOrganization(String orgId, String orgName,
			String orgDescription, int privacy) {

		validation.required(orgId);
		validation.required(orgName).message("Organization name is required");
		validation.required(orgDescription).message(
				"A brief organization description is required");
		validation.required(privacy).message(
				"Organization privacy status is required");

		int id2 = Integer.parseInt(orgId);
		long orgId2 = (long) id2;

		if (validation.hasErrors()) {
			params.flash();
			validation.keep();
			editOrg(orgId2);
		}

		Organization organization = Organization.find("byId", orgId2).first();

		organization.name = orgName;
		organization.description = orgDescription;
		organization.privacyStatus = privacy;
		organization.save();
		
		String actionLogMessage = null;
		String userName = session.get("username");
		User userForLog = User.find("userName", userName).first();
		if(userName!=null){
			actionLogMessage = "User name " + userName+ " edited an organization called " + organization.name;
			new ActionLog(actionLogMessage,userForLog,null).save();
		}
		
		if (organization != null) {
			editOrg(orgId2);
		}
				

	}

	/**
	 * The Method will remove an Idea developer from an organization as
	 * requested from the organization lead
	 * 
	 * @author shady
	 * 
	 * @param ideaDeveloperID
	 *            The id of the user who will be removed
	 * @param organizationID
	 *            The id of the organization which the user will be removed from
	 * 
	 */
	public static void removeIdeaDeveloperFromOrganizationAsLead(
			long ideaDeveloperID, long organizationID) {
		String userName = session.get("username");
		User user = User.find("userName", userName).first();

		if (user != null) {
			Organization org = Organization.findById(organizationID);

			if (Organization.removeMemberFromOrganization(user.id,
					ideaDeveloperID, organizationID)) {
				List<User> ideaDevelopers = org.getIdeaDevelopers();
				renderTemplate("Browse/viewOrganizationIdeaDevelopers.html",
						ideaDevelopers, org);
			}
		}

	}

	/**
	 * The Method will search in the list of all idea developers in a specific
	 * organization, for a given name and will return the search results
	 * 
	 * @author shady
	 * 
	 * @param query
	 *            The name that the method will search for
	 * @param organizationID
	 *            The id of the organization that the searching will occur on
	 */
	public static void searchForIdeaDeveloper(String query, long organizationID) {
		Organization org = Organization.findById(organizationID);
		List<User> ideaDevelopers = new ArrayList<User>();

		if (org != null && org.getIdeaDevelopers() != null
				&& org.getIdeaDevelopers().size() != 0) {
			for (User user : org.getIdeaDevelopers()) {
				if (user.name.toLowerCase().indexOf(query.toLowerCase()) != -1) {
					ideaDevelopers.add(user);
				}
			}

			if (query == "") {
				ideaDevelopers = org.getIdeaDevelopers();
			}

			renderTemplate("Browse/viewOrganizationIdeaDevelopers.html",
					ideaDevelopers, org);
		}
	}

	/**
	 * The Method will remove an Idea developer from an organization
	 * 
	 * @author shady
	 * 
	 * @param ideaDeveloperID
	 *            The id of the user who will be removed
	 * @param organizationID
	 *            The id of the organization which the user will be removed from
	 * 
	 */
	public static void removeIdeaDeveloperFromOrganization(
			long ideaDeveloperID, long organizationID) {
		String userName = session.get("username");
		User user = User.find("userName", userName).first();

		if (user != null) {
			if (ideaDeveloperID == user.id) {
				if (Organization.removeSelfFromOrganization(ideaDeveloperID,
						organizationID)) {
					Users.viewOrganizationsOfUser();
					// renderTemplate("Users/viewOrganizationsOfUser.html",user,);
				}
			}
		}
	}

	/**
	 * method used to call the html file to edit an org
	 * 
	 * @param id
	 *            , id of org to be edited
	 * @author Omar Fouda
	 */
	public static void editOrg(long id) {
		Organization org = Organization.findById(id);
		render(org);
	}

	/**
	 * @author Zeyad Gasser
	 * @userStory 11
	 * @component C1 renders the create organization view
	 */
	public static void createOrg() {
		String username = session.get("username");
		User userLoggedIn = User.getUserInfo(username);
		if (userLoggedIn == null) {
			render("Application/notLoggedIn.html");
		}
		render();
	}

	/**
	 * @author Zeyad Gasser
	 * @userStory 18
	 * @component C1
	 * 
	 *            Deletes an organization by its lead
	 * 
	 * @param id
	 *            , id of the organization that will be deleted
	 */
	public static void deleteOrg(long orgId) {
		Organization organizationById = Organization.findById(orgId);
		organizationById.cascadeDelete();
		String username = session.get("username");
		User user = User.getUserInfo(username);
		String msg = "User name " + user.name + " deleted organization named "
				+ organizationById.name;
		new ActionLog(msg, user, null).save();
		render("Organizations/organizationDeleted.html");
	}

	/**
	 * @author Yomna El Rashidi 
	 * 
	 * sets the value of the boolean variable in the
	 * organization that allows the idea developers to create tags to
	 * true
	 * 
	 * @param orgID
	 *            the ID of the organization to change its variable
	 */

	public static void allowTagCreation(long orgID) {
		Organization org = Organization.find("byID", orgID).first();
		if (org != null) {
			org.allowingTagCreationForDevelopers = true;
			org.save();
		}
		Browse.viewOrganization(orgID);

	}

	/**
	 * @author Yomna El Rashidi 
	 * 
	 * sets the value of the boolean variable in the
	 * organization that allows the idea developers to create tags to
	 * false
	 * 
	 * @param orgID
	 *            the ID of the organization to change its variable
	 */

	public static void stopTagCreation(long orgID) {
		Organization org = Organization.find("byID", orgID).first();
		if (org != null) {
			org.allowingTagCreationForDevelopers = false;
			org.save();
		}
		Browse.viewOrganization(orgID);
	}

	public static void getTopOrganizations() {

		List<Organization> Organizations = Organization.find(
				"order by howMuchPopular desc").fetch();
		List<Organization> topOrganizations = new ArrayList<Organization>();
		User user = User.getUserInfo(session.get("username"));
		for (Organization organization : Organizations) {
			if (!organization.isSecret()) {
				topOrganizations.add(organization);
			} else if(user != null && organization.isMember(user.id)){
				topOrganizations.add(organization);
			}
		}

		render("Application/Top Organizations.html", topOrganizations);
	}
}
